from interfaces.data_loader import IDataLoader
from interfaces.form_metadata import IFormMetadataProvider
from interfaces.transformers import IBaseSubjects, IJoiner, IPivotMetrics, IFailureList, ICycleProcessor, IBloodDraw, ILbup
from interfaces.excel_writer import IExcelWriter

from implementations.pandas_data_loader import PandasDataLoader
from implementations.form_metadata_provider import FormMetadataProvider
from implementations.excel_writer import ExcelWriter
from implementations.merge.base_subjects import BaseSubjectsTransformer
from implementations.merge.failure_list import FailureListTransformer
from implementations.merge.cycle_processor import CycleProcessor
from implementations.pivot.blood_draw import BloodDrawTransformer
from implementations.pivot.lbup import LbupTransformer
from implementations.pivot.pivot_metrics import PivotMetricsTransformer
from implementations.others.joiner import JoinerTransformer


from config import SETTINGS
from constants import COLUMNS_TO_DELETE

class Container:
    def __init__(self):
        default_source = SETTINGS['DEFAULT_SOURCE_DATA']
        default_output = SETTINGS['DEFAULT_SOURCE_DATA_TREATED']
        self.data_loader: IDataLoader = PandasDataLoader(default_source)
        self.metadata: IFormMetadataProvider = FormMetadataProvider()
        self.base_subjects: IBaseSubjects = BaseSubjectsTransformer(self.data_loader, self.metadata)
        self.joiner: IJoiner = JoinerTransformer()
        self.pivot: IPivotMetrics = PivotMetricsTransformer(default_source)
        self.failure: IFailureList = FailureListTransformer(self.data_loader, self.metadata)
        self.cycles: ICycleProcessor = CycleProcessor()
        self.blood_draw: IBloodDraw = BloodDrawTransformer(default_source, self.metadata)
        self.lbup: ILbup = LbupTransformer(default_source, self.metadata)
        self.writer: IExcelWriter = ExcelWriter(default_output, COLUMNS_TO_DELETE, self.metadata.get_column_data)

    def build_service(self):
        from services.data_processing_service import DataProcessingService
        return DataProcessingService(
            data_loader=self.data_loader,
            metadata=self.metadata,
            base_subjects=self.base_subjects,
            joiner=self.joiner,
            pivot=self.pivot,
            failure=self.failure,
            cycles=self.cycles,
            blood_draw=self.blood_draw,
            lbup=self.lbup,
            writer=self.writer,
            default_source_data=SETTINGS['DEFAULT_SOURCE_DATA'],
        )